package com.xydtech.busiflw.controller;

import com.xydtech.busiflw.domain.BusiflInstStep;
import com.xydtech.busiflw.domain.BusiflInstance;
import com.xydtech.busiflw.domain.BusiflWaitTask;
import com.xydtech.busiflw.service.IBusiflInstStepService;
import com.xydtech.busiflw.service.IBusinessFlowService;
import com.xydtech.common.annotation.RepeatSubmit;
import com.xydtech.common.core.controller.BaseController;
import com.xydtech.common.core.domain.AjaxResult;
import com.xydtech.common.core.domain.Ztree;
import com.xydtech.common.core.domain.entity.SysUser;
import com.xydtech.common.utils.ShiroUtils;
import com.xydtech.workflow.domain.WflApprauthor;
import com.xydtech.workflow.domain.WflFlowstep;
import com.xydtech.workflow.domain.WflSteppage;
import com.xydtech.workflow.service.IWflApprauthorService;
import com.xydtech.workflow.service.IWflFlowstepService;
import com.xydtech.workflow.service.IWflSteppageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

/**
 * 业务流程Controller
 *
 * @author JHON
 * @date 2021-06-09
 */
@Controller
@RequestMapping("/businessFlow")
public class BusinessFlowController extends BaseController {
    private String prefix = "busiflw";
    @Autowired
    IBusinessFlowService businessFlowService;
    @Autowired
    private IWflFlowstepService wflFlowStepService;
    @Autowired
    private IWflSteppageService wflSteppageService;
    @Autowired
    private IWflApprauthorService wflApprauthorService;
    @Autowired
    private IBusiflInstStepService busiflInstStepService;

    /**
     * 启动业务流程实例
     *
     * @param flowId
     * @param versionId
     * @param instanceId
     * @param mmap
     * @return java.lang.String
     * @throws
     * @Title: startInstance
     * @author JHON
     * @Date 2021/6/11 14:04
     **/
    @GetMapping("/startInstance/{flowId}/{versionId}/{instanceId}")
    public String startInstance(
            @PathVariable("flowId") Long flowId,
            @PathVariable("versionId") Long versionId,
            @PathVariable("instanceId") String instanceId,
            String keyInfo, ModelMap mmap) throws Exception {
        /**查询流程第一个节点信息*/
        WflFlowstep wflFlowstep = wflFlowStepService.selectWflFlowstepByVersionIdAndOrderNum(versionId, 1L);
        if (wflFlowstep == null) {
            throw new Exception("流程未配置！");
        }
        /**查询流程实例是否已被创建*/
        BusiflInstance busiflInstance = businessFlowService.selectBusiflInstanceById(instanceId);
        if (busiflInstance != null) {
            throw new Exception("本业务已在流程审批中，请到待办任务或者已提交任务查看进度！");
        }
        /**查询流程节点页面配置信息*/
        WflSteppage wflSteppage = new WflSteppage();
        wflSteppage.setVersionId(versionId);
        wflSteppage.setStepId(wflFlowstep.getStepId());
        List<WflSteppage> pageList = wflSteppageService.selectWflSteppageList(wflSteppage);
        //用户编号
        Long userId = ShiroUtils.getUserId();
        //机构部门编号
        Long deptId = ShiroUtils.getSysUser().getDeptId();
        keyInfo = java.net.URLDecoder.decode(keyInfo, "UTF-8");
        /**初始化流程*/
        BusiflWaitTask busiflWaitTask = businessFlowService.initBusinessFlowData(wflFlowstep, flowId, instanceId, userId, deptId, keyInfo.toString());

        /**查询当前节点审批权限*/
        List<WflApprauthor> appAuthorList = wflApprauthorService.selectStepApprAuthorList(versionId, wflFlowstep.getStepId());
        mmap.put("versionId", versionId);
        mmap.put("instanceId", instanceId);
        mmap.put("stepId", wflFlowstep.getStepId());
        mmap.put("taskId", busiflWaitTask.getTaskId());
        mmap.put("pageList", pageList);
        mmap.put("appAuthorList", appAuthorList);
        mmap.put("keyInfo", keyInfo);
        return prefix + "/flw_page_tabs";
    }

    /**
     * 从待办任务进入流程
     *
     * @param instanceId
     * @param stepId
     * @param taskId
     * @param mmap
     * @return java.lang.String
     * @throws
     * @Title: startInstance
     * @author JHON
     * @Date 2021/6/11 14:04
     **/
    @GetMapping("/dealWithWaitTask/{versionId}/{instanceId}/{stepId}/{taskId}")
    public String dealWithWaitTask(
            @PathVariable("versionId") Long versionId,
            @PathVariable("instanceId") String instanceId,
            @PathVariable("stepId") Long stepId,
            @PathVariable("taskId") Long taskId,
            String keyInfo, ModelMap mmap) throws UnsupportedEncodingException {

        /**查询流程节点页面配置信息*/
        WflSteppage wflSteppage = new WflSteppage();
        wflSteppage.setVersionId(versionId);
        wflSteppage.setStepId(stepId);
        List<WflSteppage> pageList = wflSteppageService.selectWflSteppageList(wflSteppage);
        /**查询当前节点审批权限*/
        List<WflApprauthor> appAuthorList = wflApprauthorService.selectStepApprAuthorList(versionId, stepId);
        mmap.put("versionId", versionId);
        mmap.put("instanceId", instanceId);
        mmap.put("stepId", stepId);
        mmap.put("taskId", taskId);
        mmap.put("pageList", pageList);
        mmap.put("appAuthorList", appAuthorList);
        mmap.put("keyInfo", java.net.URLDecoder.decode(keyInfo, "UTF-8"));
        return prefix + "/flw_page_tabs";
    }

    /**
     * 从结束任务进入流程
     *
     * @param versionId
     * @param stepId
     * @param mmap
     * @return java.lang.String
     * @throws
     * @Title: closedWaitTask
     * @author JHON
     * @Date 2021/6/11 14:04
     **/
    @GetMapping("/closedWaitTask/{versionId}/{instanceId}/{stepId}")
    public String closedWaitTask(
            @PathVariable("versionId") Long versionId,
            @PathVariable("instanceId") String instanceId,
            @PathVariable("stepId") Long stepId, ModelMap mmap) {

        /**查询流程节点页面配置信息*/
        WflSteppage wflSteppage = new WflSteppage();
        wflSteppage.setVersionId(versionId);
        wflSteppage.setStepId(stepId);
        List<WflSteppage> pageList = wflSteppageService.selectWflSteppageList(wflSteppage);
        mmap.put("versionId", versionId);
        mmap.put("instanceId", instanceId);
        mmap.put("stepId", stepId);
        mmap.put("pageList", pageList);
        return prefix + "/close_flw_page_tabs";
    }

    /**
     * 提交待办任务
     *
     * @param versionId
     * @param instanceId
     * @param stepId
     * @param taskId
     * @param keyInfo
     * @param approveType
     * @param approveMemo
     * @return com.xydtech.common.core.domain.AjaxResult
     * @throws
     * @Title: submitTask
     * @author JHON
     * @Date 2021/12/2 16:29
     **/
    @PostMapping("/submitTask")
    @ResponseBody
    @RepeatSubmit
    public AjaxResult submitTask(
            @RequestParam("versionId") Long versionId,
            @RequestParam("instanceId") String instanceId,
            @RequestParam("stepId") Long stepId,
            @RequestParam("taskId") Long taskId,
            @RequestParam("keyInfo") String keyInfo,
            @RequestParam("approveType") String approveType,
            @RequestParam("approveMemo") String approveMemo) throws Exception {
        String salt = getSalt();//盐值
        return businessFlowService.submitTask(versionId, instanceId, stepId, taskId, keyInfo, approveType, approveMemo, ShiroUtils.getSysUser(), "", salt);
    }

    /**
     * 提交待办任务(包含选择的下一节点审批人)
     *
     * @param versionId
     * @param instanceId
     * @param stepId
     * @param taskId
     * @param keyInfo
     * @param approveType
     * @param approveMemo
     * @param choiceApproveUserList
     * @return com.xydtech.common.core.domain.AjaxResult
     * @throws
     * @Title: submitTaskIncludeApproveUserList
     * @author JHON
     * @Date 2021/12/3 15:03
     **/
    @PostMapping("/submitTaskIncludeApproveUserList")
    @ResponseBody
    @RepeatSubmit
    public AjaxResult submitTaskIncludeApproveUserList(
            @RequestParam("versionId") Long versionId,
            @RequestParam("instanceId") String instanceId,
            @RequestParam("stepId") Long stepId,
            @RequestParam("taskId") Long taskId,
            @RequestParam("keyInfo") String keyInfo,
            @RequestParam("approveType") String approveType,
            @RequestParam("approveMemo") String approveMemo,
            @RequestParam("choiceApproveUserList") String choiceApproveUserList) throws Exception {
        String salt = getSalt();//盐值
        return businessFlowService.submitTask(versionId, instanceId, stepId, taskId, keyInfo, approveType, approveMemo, ShiroUtils.getSysUser(), choiceApproveUserList, salt);
    }

    /**
     * 获取下一节点信息
     *
     * @param versionId
     * @param stepId
     * @return com.xydtech.common.core.domain.AjaxResult
     * @throws
     * @Title: getNextStep
     * @author JHON
     * @Date 2021/12/2 16:28
     **/
    @PostMapping("/getNextStep")
    @ResponseBody
    public AjaxResult getNextStep(@RequestParam("versionId") Long versionId, @RequestParam("stepId") Long stepId, @RequestParam("instanceId") String instanceId, @RequestParam("keyInfo") String keyInfo) {
        /**查询流程当前节点信息*/
        WflFlowstep wflFlowstep = new WflFlowstep();
        wflFlowstep.setVersionId(versionId);
        wflFlowstep.setStepId(stepId);
        wflFlowstep.setSts("1");
        List<WflFlowstep> stepList = wflFlowStepService.selectWflFlowstepList(wflFlowstep);
        if (stepList.size() > 0) {
            return AjaxResult.success(businessFlowService.getNextStepInfo(stepList.get(0).getVersionId(), stepList.get(0).getOrderNum(), instanceId, keyInfo));
        } else {
            return error("流程节点未配置!");
        }
    }


    /**
     * 选择下一节点审批人
     *
     * @param versionId
     * @param instanceId
     * @param stepId
     * @param keyInfo
     * @param mmap
     * @return java.lang.String
     * @throws
     * @Title: selectApproveUserList
     * @author JHON
     * @Date 2021/12/3 15:31
     **/
    @GetMapping("/selectApproveUserList/{versionId}/{instanceId}/{stepId}")
    public String selectApproveUserList(
            @PathVariable("versionId") Long versionId,
            @PathVariable("instanceId") String instanceId,
            @PathVariable("stepId") Long stepId, String keyInfo,
            ModelMap mmap) throws UnsupportedEncodingException {
        String salt = getSalt();//盐值
        WflFlowstep wflFlowstep = new WflFlowstep();
        wflFlowstep.setVersionId(versionId);
        wflFlowstep.setStepId(stepId);
        List<WflFlowstep> wflFlowStepList = wflFlowStepService.selectWflFlowstepList(wflFlowstep);
        /**查询下一节点信息*/
        WflFlowstep nextStep = businessFlowService.getNextStepInfo(versionId, wflFlowStepList.get(0).getOrderNum(), instanceId, keyInfo);
        List<Ztree> zTrees = new ArrayList<Ztree>();
        /**查询下一节点审批用户*/
        List<SysUser> userList = businessFlowService.getApproveUserList(instanceId, nextStep, ShiroUtils.getSysUser(), "", salt);
        //审批人
        mmap.put("userList", userList);
        //审批人数
        mmap.put("approvePop", nextStep.getApprovPop());
        mmap.put("stepName", nextStep.getStepName());
        return prefix + "/approveUserList";
    }

    /**
     * 流程审批列表
     *
     * @param instanceId
     * @param mmap
     * @return java.lang.String
     * @throws
     * @Title: approveList
     * @author JHON
     * @Date 2022/1/7 14:36
     **/
    @GetMapping("/approveList/{instanceId}")
    public String approveList(@PathVariable("instanceId") String instanceId, ModelMap mmap) {
        BusiflInstStep busiflInstStep = new BusiflInstStep();
        busiflInstStep.setInstanceId(instanceId);
        List<BusiflInstStep> instStepList = busiflInstStepService.selectBusiflInstApproveList(busiflInstStep);
        mmap.put("instStepList", instStepList);
        return prefix + "/approveList";
    }

    /**
     * 获取节点页面配置信息
     *
     * @param versionId
     * @param stepId
     * @return com.xydtech.common.core.domain.AjaxResult
     * @throws
     * @Title: getPageList
     * @author JHON
     * @Date 2022/7/7 14:13
     **/
    @PostMapping("/getPageList")
    @ResponseBody
    public AjaxResult getPageList(@RequestParam("versionId") Long versionId, @RequestParam("stepId") Long stepId) {
        /**查询流程节点页面配置信息*/
        WflSteppage wflSteppage = new WflSteppage();
        wflSteppage.setVersionId(versionId);
        wflSteppage.setStepId(stepId);
        List<WflSteppage> pageList = wflSteppageService.selectWflSteppageList(wflSteppage);
        if (pageList.size() > 0) {
            return AjaxResult.success(pageList);
        } else {
            return error("流程节点未配置!");
        }
    }


    @GetMapping("/approvaPage/{versionId}/{instanceId}/{stepId}/{taskId}")
    public String approvaPage(@PathVariable("versionId") Long versionId,
                              @PathVariable("instanceId") String instanceId,
                              @PathVariable("stepId") Long stepId,
                              @PathVariable("taskId") Long taskId,
                              String keyInfo, ModelMap mmap) throws UnsupportedEncodingException {
        /**查询当前节点审批权限*/
        List<WflApprauthor> appAuthorList = wflApprauthorService.selectStepApprAuthorList(versionId, stepId);
        mmap.put("versionId", versionId);
        mmap.put("instanceId", instanceId);
        mmap.put("stepId", stepId);
        mmap.put("taskId", taskId);
        mmap.put("appAuthorList", appAuthorList);
        mmap.put("keyInfo", java.net.URLDecoder.decode(keyInfo, "UTF-8"));
        return prefix + "/waittask/flw_approval_page";
    }
}
